package cn.sunshine.ymcc.service.impl;

import cn.sunshine.ymcc.domain.KillActivity;
import cn.sunshine.ymcc.domain.KillCourse;
import cn.sunshine.ymcc.mapper.KillActivityMapper;
import cn.sunshine.ymcc.service.IKillActivityService;
import cn.sunshine.ymcc.service.IKillCourseService;
import cn.sunshine.ymcc.util.AssertUtil;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.redisson.api.RSemaphore;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author Mr.Jiang
 * @since 2022-08-23
 */
@Service
public class KillActivityServiceImpl extends ServiceImpl<KillActivityMapper, KillActivity> implements IKillActivityService {
    // 自己new一个时间段格式
    private static SimpleDateFormat timeStr = new SimpleDateFormat("MM-dd HH:mm");
    @Autowired
    private IKillCourseService killCourseService;
    @Autowired
    private RedisTemplate<Object,Object> redisTemplate;
    @Autowired
    private RedissonClient redissonClient;
    @Override
    public void insertActivity(KillActivity killActivity) {
        String format = timeStr.format(killActivity.getBeginTime());
        killActivity.setTimeStr(format);
        insert(killActivity);
    }


    /**
    * @Title: publish
    * @Description: 发布秒杀
    * @Author: Mr.Jiang
    * @Version: 1.0
    * @Date:  2022/8/23 22:14
    * @Parameters: [activityId]
    * @Return void
    */
    @Override
    public void publish(Long activityId) {
    // 1.查看活动是否存在
        KillActivity killActivity = selectById(activityId);
        AssertUtil.isNotNull(killActivity,"活动不存在，请重新选择新活动");

   // 2.判断该活动状态是不是待发布
        boolean notPublish = killActivity.getPublishStatus() == KillActivity.KILL_STATUS_PUBLISH;
        AssertUtil.isTrue(notPublish,"活动正在进行中或者已下架");
       // 3.当前系统时间小于活动开始时间（是就说明还可以发布，不是就说明错过了）
        boolean before = new Date().before(killActivity.getEndTime());
        AssertUtil.isTrue(before,"活动时间不合法");

        // 修改活动状态
        killActivity.setPublishStatus(KillActivity.KILL_STATUS_KILLING);
        killActivity.setPublishTime(new Date());
        updateById(killActivity);
    // 4.将对应的秒杀课程存在redis
        Wrapper<KillCourse> Wrapper = new EntityWrapper<>();
        Wrapper.eq("activity_id",activityId);
        List<KillCourse> killCourses = killCourseService.selectList(Wrapper);
        killCourses.stream().forEach(killCourse->{
                    // 5.将秒杀库存存成信号量
            String semaphoreKey = killActivity.getId() + ":" + killCourse.getId();
            RSemaphore semaphore = redissonClient.getSemaphore(semaphoreKey);
                 // 尝试设置库存
                    boolean success = semaphore.trySetPermits(killCourse.getKillCount());
                 if(success){
            // 6.将对应的秒杀课程存在redis  hash也需要序列化，只是已经做了就在本项目的 RedisConfig 配置文件中
            redisTemplate.opsForHash().put(
                    "activity:"+activityId,
                    killCourse.getId().toString(),
                    killCourse);

                 }else {
                     // 兜底数据
                 }
            // 修改秒杀课程状态
            killCourse.setPublishStatus(killActivity.getPublishStatus());
            killCourse.setPublishTime(killActivity.getPublishTime());
            killCourseService.updateById(killCourse);
        });
        // 修改活动状态
        //killActivity.setPublishStatus(KillActivity.KILL_STATUS_KILLING);

    }
}
